/***************************************************************************
 *   Copyright (C) 2006 by Archimedes Projekt   *
 *   thelsb@gmail.com   *
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 *   This program is distributed in the hope that it will be useful,       *
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 *   GNU General Public License for more details.                          *
 *                                                                         *
 *   You should have received a copy of the GNU General Public License     *
 *   along with this program; if not, write to the                         *
 *   Free Software Foundation, Inc.,                                       *
 *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
 ***************************************************************************/
#include "hpsccommadthread.h"
#include <iostream>
#include <QString>
#include <QMutex>
#include <QtDebug>
#include "qextserialport.h"
#include "gssglobals.h"
#include <QApplication>

HPSCCommandThread::HPSCCommandThread(QextSerialPort *serial):
m_serial(serial)
{
}


HPSCCommandThread::~HPSCCommandThread()
{
}


/*!
    \fn HPSCCommadThread::run()
 */
void HPSCCommandThread::run()
{
	exec();
}


/*!
    \fn HPSCCommandThread::addCommand(QString cmd,long usWait)
 */
void HPSCCommandThread::postCommand(QString cmd,long usWait)
{
	qDebug()<<"HPSCCommandThread::postCommand----------------------"<<cmd;
	QPair<QString,long> command(cmd,usWait);
	m_commandListMutex.lock();
	m_listCommands.push_back(command);
	m_commandListMutex.unlock();
}


/*!
    \fn HPSCCommandThread::customEvent(QEvent *event)
 */
void HPSCCommandThread::customEvent(QEvent *event)
{
	QPair<QString,long> currentCmd;
	int bytes = 0;
	quint8 *data=NULL;
	QString strData;
    int cmdSize;
	
	switch(event->type())
	{
		case HPSCMEAS:
			//qDebug()<<"HPSCMEAS";
            currentCmd = ((HPSCEventBase*)event)->strCmdWait();
            cmdSize = currentCmd.first.size()+1;
            //qDebug()<<"sending:"<<currentCmd.first;
            currentCmd.first += '\r';
            
			if(m_serialMutex.tryLock())
			{
                if(m_serial->isOpen())
                {	
                    //clear buffer if full with garbage
                    bytes = m_serial->bytesAvailable();
                    if(bytes>500)
                    {
                        data = new quint8[bytes];
                        m_serial->readData((char*)data,bytes);
                        memset(data,0,bytes);
                        qDebug()<<"serial cleared";
                    }
                    ///////
                    m_serial->writeData(currentCmd.first.toAscii().data(),cmdSize);
				    usleep(currentCmd.second);
                    bytes = m_serial->bytesAvailable();
                    //qDebug()<<"bytes:"<<bytes;
                    if(currentCmd.first.contains("VOLT") || currentCmd.first.contains("CURR") )
                    {
                        int cnt = 0;
                        while(bytes < 3 && cnt < 100)
                        {
                            
                            //qDebug()<<"bytes:"<<bytes;
                            msleep(10);
                            bytes = m_serial->bytesAvailable();
                            QApplication::processEvents();
                            cnt++;
                            
                        }
                        if(cnt > 99)
                        {
                            emit sig_readoutV(1,"0.0");
                            emit sig_readoutV(2,"0.0");
                            emit sig_readoutV(3,"0.0");
                            emit sig_readoutV(4,"0.0");
                            emit sig_readoutA(1,"0.0");    
                            emit sig_readoutA(2,"0.0");    
                            emit sig_readoutA(3,"0.0");    
                            emit sig_readoutA(4,"0.0");    
                        }
                    }
                    if(!data && bytes>0 )
                    {
                        data = new quint8[bytes];
                        memset(data,0,bytes);
                    }
                    //qDebug()<<"bytes:"<<bytes;
				    if(bytes > 0 && m_serial->readData((char*)data,bytes) != -1)
				    {
					   //qDebug()<<"reading";
					   for(int i=0;i<bytes;i++)
					   {
                           //qDebug()<<data[i];
                         //  printf("==%c(%d) ",data[i],data[i]);
						  if(data[i] > 45 && data[i] < 58)
							 strData += data[i];
						  if(data[i]==13) break;    
					   }
					   
				    }
                    
				    if(data) delete []data;
                    if(currentCmd.first.contains("VOLT1"))
                    {
                        //qDebug()<<"got VOLT1 "<<strData;
                        emit sig_readoutV(1,strData);
                    }
                    if(currentCmd.first.contains("VOLT2"))
                    {
                        //qDebug()<<"got VOLT2 "<<strData;
                        emit sig_readoutV(2,strData);    
                    }
				    if(currentCmd.first.contains("VOLT3")) 
                    {
                       // qDebug()<<"got VOLT3 "<<strData;
                        emit sig_readoutV(3,strData);	
                    }
				    if(currentCmd.first.contains("VOLT4")) 
                    {
                        //qDebug()<<"got VOLT4 "<<strData;
                        emit sig_readoutV(4,strData);
                    }
                    if(currentCmd.first.contains("CURR1")) 
                    {
                        //qDebug()<<"got CURR1 "<<strData;
                        emit sig_readoutA(1,strData);                
                    }
                    if(currentCmd.first.contains("CURR2")) 
                    {
                        //qDebug()<<"got CURR2 "<<strData;
                        emit sig_readoutA(2,strData);            
                    }
				    if(currentCmd.first.contains("CURR3")) 
                    {
                        //qDebug()<<"got CURR3 "<<strData;
                        emit sig_readoutA(3,strData);			
                    }
				    if(currentCmd.first.contains("CURR4")) 
                    {
                        //qDebug()<<"got CURR4 "<<strData;
                        emit sig_readoutA(4,strData);					
                    }
                    if(!currentCmd.first.contains("VOLT") && !currentCmd.first.contains("CURR"))
                    {
                        //qDebug()<<"got ELSE "<<strData;
                        emit sig_readout(strData);
                    }
                    emit sig_pollNext();
 				}	
				m_serialMutex.unlock();
			}
			break;
		case HPSCSTRVAL:qDebug()<<"HPSCSTRVAL";
            currentCmd.first = ((HPSCEventBase*)event)->strCmdWait().first;
			currentCmd.first += '\r';
            if(m_serialMutex.tryLock())
			{
                if(m_serial->isOpen())
                {
				    m_serial->writeData(currentCmd.first.toAscii().data(),currentCmd.first.size());
				    usleep(currentCmd.second);
                }
    		    m_serialMutex.unlock();
			}
			break;
		
            case HPSCEventSerial:
                if(m_serialMutex.tryLock())
                {
                    if(((HPSCEventBase*)event)->serialConnect() && !m_serial->isOpen())
                    {
                    if(!m_serial->open())
                        qWarning()<<"HPSC coulnd not open serial port "<<m_serial->portName();
                    else qWarning()<<"HPSC opened "<<m_serial->portName();
                    }
                    if(!((HPSCEventBase*)event)->serialConnect() && m_serial->isOpen())
                    {
                    m_serial->close();
                    if(m_serial->isOpen())
                        qWarning()<<"HPSC coulnd not close serial port "<<m_serial->portName();
                    else qWarning()<<"HPSC close "<<m_serial->portName();
                    }
                }
                m_serialMutex.unlock();
            break;
            default: break;
	}
}
